#include <iostream>
#include <future>
#include <thread>
/*
    packaged_task：类模板，任务包装器；
        将任务包装成一个可调用对象，在异步线程中调用执行任务，在主线程中获取任务对象关联的future对象，通过future对象来获取异步结果；
        用法类似与function；
*/
int add(int a, int b)
{
    std::cout << "add\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return a + b;
}

int main()
{
    // 用智能指针来管理任务对象，因为下面创建线程来执行任务，传入的是一个匿名函数，匿名函数传值捕获的时候，任务对象会发生拷贝构造
    // 而packaged_task不允许拷贝构造
    // 1、封装任务
    auto task = std::make_shared<std::packaged_task<int(int, int)>>(add);
    
    // 2、获取任务包关联的future对象
    std::future<int> res = task->get_future();

    // 3、异步执行任务
    std::thread td([&task](){
        (*task)(1, 2);
    });

    // 4、获取结果
    std::cout << res.get() << std::endl; // 内部阻塞主线程，直到获取到结果
    std::cout << "main thread" << std::endl;
    td.join();
    return 0;
}